package org.fujay.langchain4jserver.application.assembler;

import cn.hutool.core.collection.CollUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.fujay.langchain4jserver.application.dto.*;
import org.fujay.langchain4jserver.domain.knowledge.aggregate.KnowledgeBaseAggregate;
import org.fujay.langchain4jserver.domain.knowledge.entity.File;
import org.fujay.langchain4jserver.domain.knowledge.entity.KnowledgeBase;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 知识库聚合 与 DTO 之间的转换器
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class KnowledgeBaseAssembler {

    public static KnowledgeBaseSummaryDTO toSummaryDTO(final KnowledgeBaseAggregate aggregate) {
        if (aggregate == null) {
            return null;
        }
        KnowledgeBase kb = aggregate.getKnowledgeBase();
        return KnowledgeBaseSummaryDTO.builder()
                .id(kb.getId().value())
                .name(kb.getName())
                .description(kb.getDescription())
                .embeddingModelId(kb.getEmbeddingModelId().value())
                .status(kb.getStatus().name())
                .build();
    }

    public static List<KnowledgeBaseSummaryDTO> toSummaryDTOList(
            final List<KnowledgeBaseAggregate> aggregates) {
        if (CollUtil.isEmpty(aggregates)) {
            return Collections.emptyList();
        }
        return aggregates.stream()
                .map(KnowledgeBaseAssembler::toSummaryDTO)
                .collect(Collectors.toList());
    }

    public static KnowledgeBaseDetailDTO toDetailDTO(final KnowledgeBaseAggregate aggregate) {
        if (aggregate == null) return null;
        KnowledgeBaseDetailDTO dto = new KnowledgeBaseDetailDTO();
        dto.setId(aggregate.getId().value());
        dto.setName(aggregate.getName());
        dto.setDescription(aggregate.getDescription());
        dto.setStatus(aggregate.getStatus());
        dto.setEmbeddingModelId(
                aggregate.getEmbeddingModelId() != null ? aggregate.getEmbeddingModelId().value() : null);
        dto.setCreatedAt(
                aggregate.getCreatedAt() != null
                        ? aggregate.getCreatedAt().toString()
                        : null); // Use getter
        dto.setUpdatedAt(
                aggregate.getUpdatedAt() != null
                        ? aggregate.getUpdatedAt().toString()
                        : null); // Use getter
        // TODO: Potentially add file list summary here later
        return dto;
    }

    public static FileSummaryDTO toFileSummaryDTO(final File file) {
        if (file == null) return null;
        FileSummaryDTO dto = new FileSummaryDTO();
        dto.setId(file.getId().value());
        dto.setKnowledgeBaseId(file.getKnowledgeBaseId().value());
        dto.setFileName(file.getFileName());
        dto.setFileType(file.getFileType());
        dto.setFileSize(file.getFileSize());
        dto.setIndexStatus(file.getIndexStatus());
        dto.setErrorMessage(file.getErrorMessage());
        dto.setStorageStrategy(file.getStorageStrategy());
        dto.setCreatedAt(file.getCreateTime() != null ? file.getCreateTime().toString() : null);
        dto.setUpdatedAt(file.getUpdateTime() != null ? file.getUpdateTime().toString() : null);
        return dto;
    }

    public static List<FileSummaryDTO> toFileSummaryDTOList(final List<File> files) {
        if (files == null) return List.of();
        return files.stream()
                .map(KnowledgeBaseAssembler::toFileSummaryDTO)
                .collect(Collectors.toList());
    }

    public static FileDTO toDTO(final File file) {
        if (file == null) {
            return null;
        }
        return FileDTO.builder()
                .id(file.getId().value())
                .fileName(file.getFileName())
                .fileType(file.getFileType())
                .fileSize(file.getFileSize())
                .filePath(file.getFilePath())
                .status(file.getIndexStatus().name())
                .statusMessage(file.getErrorMessage())
                .build();
    }

    public static List<FileDTO> toFileDTOList(final List<File> files) {
        if (files == null) {
            return Collections.emptyList();
        }
        return files.stream().map(KnowledgeBaseAssembler::toDTO).collect(Collectors.toList());
    }

    public static KnowledgeBaseDTO toDTO(
            final KnowledgeBaseAggregate aggregate, final KnowledgeBaseIndexStatusDTO indexStatus) {
        if (aggregate == null) {
            return null;
        }
        KnowledgeBase kb = aggregate.getKnowledgeBase();
        List<FileDTO> fileDTOs = toFileDTOList(aggregate.listFiles());

        return KnowledgeBaseDTO.builder()
                .id(kb.getId().value())
                .name(kb.getName())
                .description(kb.getDescription())
                .embeddingModelId(kb.getEmbeddingModelId().value())
                .status(kb.getStatus().name())
                .files(fileDTOs)
                .indexStatus(indexStatus)
                .build();
    }
}
